package inteligencia_mapa;


import inteligencia_personaje.MovimientosPersonaje;

import java.awt.Container;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.Vector;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

import TDADiccionario.Entry;
import TDAListaSE.Iterator;

import recursos.Coordenada;

import roles.Bala;
import roles.Malo;

import main.Programa;
import entidades.Ladrillo;
import entidades.PowerUp;


public class MovimientoMapa extends Thread {
	
	protected Gravedad gravedadMario;
	protected Programa elPrograma;
	protected Container frame;
	protected int VELOCIDAD = 4;
	protected int CAPACIDAD_SALTO = 32;
	
	
	//variables utilizadas para controlar el movimiento a realizar.
	protected boolean moverPadelante;
	protected boolean moverPatras;
	protected boolean saltar;
	protected boolean saltarYcorrer;

	
	public MovimientoMapa( Container jf,Programa prog ){
		frame = jf;
		elPrograma = prog;
		moverPadelante = false;
		moverPatras = false;
		saltar = false;
		saltarYcorrer = false;
		gravedadMario = new Gravedad(elPrograma, this, elPrograma.obtenerMario());
		
	}

	
	public void refreshMapa(final int desfasaje){
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try{
					JLabel labelaux;
				
					//despintar
					for(int i = 0 ; i < desfasaje ; i++){
						Iterator<Entry<Integer,Ladrillo>> it = elPrograma.obtenerLadrillosX(i);
							while(it.hasNext()){
								Ladrillo aux = it.next().getValue();
								labelaux = aux.obtenerRepresentacionGrafica();
								frame.remove(labelaux);
							}
					}
					for(int i = 0 ; i < desfasaje ; i++){
						Iterator<Entry<Integer,PowerUp>> it = elPrograma.obtenerPowersUpsX(i);
							while(it.hasNext()){
								PowerUp aux = it.next().getValue();
								labelaux = aux.obtenerRepresentacionGrafica();
								frame.remove(labelaux);
							}
					}
	
					
					//pintar
					for(int i = desfasaje ; i < (1000+desfasaje) ; i++){
						Iterator<Entry<Integer,Ladrillo>> it = elPrograma.obtenerLadrillosX(i);
						while(it.hasNext()){
							Ladrillo aux = it.next().getValue();
							labelaux = aux.obtenerRepresentacionGrafica();
							labelaux.setLocation(aux.obtenerCoordenada().obtenerX() - desfasaje, aux.obtenerCoordenada().obtenerY());
							frame.add(labelaux);
						}
					}
					for(int i = desfasaje ; i < (1000+desfasaje) ; i++){
						Iterator<Entry<Integer,PowerUp>> it = elPrograma.obtenerPowersUpsX(i);
						while(it.hasNext()){
							PowerUp aux = it.next().getValue();
							if(aux.obtenermostrar()){
								labelaux = aux.obtenerRepresentacionGrafica();
								labelaux.setLocation(aux.obtenerCoordenada().obtenerX() - desfasaje, aux.obtenerCoordenada().obtenerY());
								frame.add(labelaux);}
						}
					}
					despintarBalas();
					pintarBalas();
					pintarMalos(desfasaje);
					despintarMalos(desfasaje);
					elPrograma.obtenerMario().obtenerRepresentacionGrafica().setLocation(128, elPrograma.obtenerMario().obtenerCoordenada().obtenerY());
					frame.add(elPrograma.obtenerMario().obtenerRepresentacionGrafica());
				}catch(TDAListaSE.NoSuchElementException e){
						e.printStackTrace();
				}
			}
		});
	}
	
	public void despintarMalos(int desfasaje){
		Iterator<Entry<Integer, Malo>> it = elPrograma.obtenerMalos();
		while(it.hasNext()){
			try {
				JLabel laux;
				Malo aux = it.next().getValue();
				if(!(aux.obtenerCoordenada().obtenerX() > desfasaje && aux.obtenerCoordenada().obtenerX() < desfasaje + 1000)){
					laux = aux.obtenerRepresentacionGrafica();
					frame.remove(laux);
				}
			} catch (TDAListaSE.NoSuchElementException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public void pintarMalos(int desfasaje){
		Iterator<Entry<Integer, Malo>> it = elPrograma.obtenerMalos();
		while(it.hasNext()){
			try {
				JLabel laux;
				Malo aux = it.next().getValue();
				if(aux.obtenerCoordenada().obtenerX() > desfasaje && aux.obtenerCoordenada().obtenerX() < desfasaje + 1000 && aux.obtenerCoordenada().obtenerY() < 448){
					if(!aux.obtenerHilo().isAlive()){
						aux.activar();
					}
					laux = aux.obtenerRepresentacionGrafica();
					laux.setLocation(aux.obtenerCoordenada().obtenerX() - elPrograma.obtenerActualX(), aux.obtenerCoordenada().obtenerY());
					frame.add(laux);
				}
			} catch (TDAListaSE.NoSuchElementException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public void despintarBalas(){
		for(int i = 0; i<elPrograma.obtenerLasBalas().size();i++){
			Bala baux = elPrograma.obtenerLasBalas().get(i);
			JLabel aux = baux.obtenerRepresentacionGrafica();
			if(!baux.obtenerEstado()){
				frame.remove(aux);
			}
		}
	}
	
	public void pintarBalas(){
		for(int i = 0; i<elPrograma.obtenerLasBalas().size();i++){
			Bala baux = elPrograma.obtenerLasBalas().get(i);
			JLabel aux = baux.obtenerRepresentacionGrafica();
			aux.setLocation(baux.obtenerCoordenada().obtenerX()- elPrograma.obtenerActualX(), baux.obtenerCoordenada().obtenerY());
			if(baux.obtenerEstado())
				frame.add(aux);
		}
	}
	
	public Container obtenerContainer(){
		return frame;
	}

	public void detener(){
		moverPadelante = false;
		moverPatras = false;
	}
	
	public void comenzarAdelante(){
		moverPadelante = true;
		moverPatras = false;
	}
	
	public void comenzarAtras(){
		moverPatras = true;
		moverPadelante = false;
	}
	
	public void saltar(boolean estaCorriendo){
		if(estaCorriendo){
			saltarYcorrer = true;
			saltar = false;
		}else{
			saltarYcorrer = false;
			saltar = true;
		}
	}


	public void run(){
		while (true){
			try{
				if(!saltarYcorrer && !moverPadelante && !moverPatras && !saltar)
					elPrograma.obtenerMario().parar();
				MovimientosPersonaje movMario = elPrograma.obtenerMario().obtenerMovPJ();
				if(moverPadelante && movMario.puedo_ir_derecha()){
					elPrograma.obtenerMario().irDerecha(VELOCIDAD);
					elPrograma.establecerActualX(elPrograma.obtenerActualX()+VELOCIDAD);
					refreshMapa(elPrograma.obtenerActualX());
					sim_grav(0);
					Thread.sleep(25);
				}
				if(moverPatras && movMario.puedo_ir_izquierda()){
					elPrograma.obtenerMario().irIzquierda(VELOCIDAD);
					elPrograma.establecerActualX(elPrograma.obtenerActualX()-VELOCIDAD);
					refreshMapa(elPrograma.obtenerActualX());
					sim_grav(0);
					Thread.sleep(25);
				}
				if(saltar){
					int i = 0;
					while(i<CAPACIDAD_SALTO && movMario.puedo_ir_arriba() ){
						elPrograma.obtenerMario().saltar(VELOCIDAD, 0);
						refreshMapa(elPrograma.obtenerActualX());
						Thread.sleep(25);
						i ++;
					}
					sim_grav(0);
					saltar = false;
				}
				if(saltarYcorrer){
					if(moverPadelante){ 
						int i = 0;
						while(i<CAPACIDAD_SALTO && movMario.puedo_ir_arriba() && movMario.puedo_ir_derecha()){
							elPrograma.obtenerMario().saltar(VELOCIDAD, 1);
							elPrograma.establecerActualX(elPrograma.obtenerActualX()+VELOCIDAD);
							refreshMapa(elPrograma.obtenerActualX());
							i++;
							Thread.sleep(25);
						}
						sim_grav(VELOCIDAD);
					}else{
						int i = 0;
						while(i<CAPACIDAD_SALTO && movMario.puedo_ir_arriba() && movMario.puedo_ir_izquierda()){
							elPrograma.obtenerMario().saltar(VELOCIDAD, 2);
							elPrograma.establecerActualX(elPrograma.obtenerActualX()-VELOCIDAD);
							refreshMapa(elPrograma.obtenerActualX());
							i++;
							Thread.sleep(25);
						}
						sim_grav(-VELOCIDAD);
					}
				}
				saltarYcorrer = false;
				Thread.sleep(75);
			}catch( Exception e ){
			}
		}
	}
	
	protected void sim_grav(int des){
		while(gravedadMario.puedo_bajar()){
			gravedadMario.tirar_para_abajo(des);
			try {
				Thread.sleep(30);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
